package com.sumainfor.pc.market.controller.jianrongjiayuan;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.Date;

public class GuomiServerDemo {
	private static String secureType = "guomiSM";

	public static void main(String[] args) throws Exception {
		String listenPort = "9000";
		//获取传入参数
		if(args.length>=1) listenPort = args[0];

		System.out.println("GuomiServer开始监听端口"+listenPort+"，准备接收HTTP请求\n");
		InetSocketAddress inetSocketAddress =  new InetSocketAddress(Integer.parseInt(listenPort));
		HttpServer server = HttpServer.create(inetSocketAddress, 0);
        server.createContext("/P5HPC", new HttpServerHandler());
        server.start();
	}

    public static class HttpServerHandler implements HttpHandler{
    	@Override
	    public void handle(HttpExchange exchange) { 
    		new Thread(new HttpReqHandler(exchange)).start();
    	}
 
    	class HttpReqHandler implements Runnable{
    		HttpExchange exchange;
    		public HttpReqHandler(HttpExchange exchange){
    			this.exchange=exchange;
    		}
    		public void run() {
    			try {
    				System.out.println("--------GuomiServer接收到一个HTTP请求--------");
    				byte[] messageHead = new byte[20];
    				InputStream in = exchange.getRequestBody();
    				OutputStream out = exchange.getResponseBody();
 
    				byte[] messageBody = GuomiServerDemo.recvAndResponse(in,messageHead);
    				if (messageBody != null) {
    					Headers responseHeaders = exchange.getResponseHeaders();
    					responseHeaders.set("Server",         "P5HPC");
    					responseHeaders.set("Content-Length", String.format("%d", messageHead.length+messageBody.length));
    		            responseHeaders.set("Content-Type",   "txt/html");
    		            exchange.sendResponseHeaders(200, messageHead.length+messageBody.length);

    					out.write(messageHead);
    	    			out.write(messageBody);
    	    			out.flush();
    	    			out.close();
    				} else
    					exchange.sendResponseHeaders(500, 0);

    				in.close();
    				System.out.println("--------GuomiServer处理完成一个HTTP请求--------\n");
    			} catch (Exception e) {
    				System.out.println(e.getMessage());
    			}
    		}
    	}
    }
    	
    public static byte[] recvAndResponse(InputStream in,byte[] messageHead) throws Exception{
    	int totalBytesRcvd = in.read(messageHead, 0, 20);//接收
		if(totalBytesRcvd<20) throw new Exception("接收长度不足20位: " + totalBytesRcvd);

		//处理返回报文
		String nodeid = NetTool.getNodeidFromHead(messageHead);
		String singType = NetTool.getSingTypeFromHead(messageHead);
		int recvLen = NetTool.getRecvLenFromHead(messageHead);
		byte[] recvByte = new byte[recvLen];//接收数据缓冲
		totalBytesRcvd = in.read(recvByte, 0, recvLen);//接收全部报文

		//报文接收不全
		if(totalBytesRcvd!=recvLen)
		{
			System.out.printf(String.format("报文实际长度[%d]与指定长度[%d]不符\n\n", totalBytesRcvd,recvLen));
			return null;
		}
		System.out.printf("接收报文长度[%d]\n", recvLen);
    	System.out.printf("secureType=[%s] nodeId=[%s]\n",secureType,nodeid);

    	byte[] messageBody  = null;
    	byte[] messageHead1 = null;
		if(singType.equalsIgnoreCase("0")) //需要解密
		{
			//获取会话密钥，设置加解密参数
	    	SecureTool secureTool = new SecureTool();
	    	if(secureTool.updateKeyInfo(secureType,nodeid) == false) return null;
	    	secureTool.printSessionKey();
	    	
	    	//执行解密过程
	    	NetTool.printEncMessage("接收的密文",recvByte,recvLen);
	    	messageBody = secureTool.decrypt(recvByte); //解密

			String recvMessage = new String(messageBody, "UTF-8");
			String messageFile = NetTool.getTranCD(recvMessage);
			if(messageFile==null)
			{
				System.out.println("请求报文中无法找到节点：/head/LH_TRAN_CD");
				return null;
			}
			String messageFile1 = String.format("%s.%s",messageFile,Long.toString(new Date().getTime()));

			System.out.printf("已解密报文[%d]=[%s]\n", recvMessage.length(), recvMessage);
			FileTool.String2File(messageFile1,recvMessage);
			System.out.printf("已解密报文已写入文件[%s]\n\n",messageFile1);

			//返回报文，直接从文件读取
			byte[] messageByte = FileTool.File2Bytes(messageFile);
			System.out.printf("返回报文message=[%d] [%s]\n",messageByte.length,new String(messageByte,"UTF-8"));

			messageBody = secureTool.encrypt(messageByte); //加密
			NetTool.printEncMessage("返回的密文",messageBody,messageBody.length);
			messageHead1 = NetTool.getMessageHead(nodeid,singType,messageBody.length);
		}
		else
		{
			messageBody = recvByte;
	
			String recvMessage = new String(messageBody, "UTF-8");
			String messageFile = NetTool.getTranCD(recvMessage);
			if(messageFile==null)
			{
				System.out.println("请求报文中无法找到节点：/head/LH_TRAN_CD");
				return null;
			}
			String messageFile1 = String.format("%s.%s",messageFile,Long.toString(new Date().getTime()));

			System.out.printf("未加密报文[%d]=[%s]\n", recvLen, recvMessage);
			FileTool.String2File(messageFile1,recvMessage);
			System.out.printf("未加密报文已写入文件[%s]\n\n",messageFile1);
			
			//获取handkey
			SecureTool secureTool = new SecureTool();
			String handKey = secureTool.getHandKey(secureType,nodeid);

			//返回报文，获取签名值
			String singMessage = String.format(MessageTool.getSignRetMessage(),handKey);
			System.out.printf("返回报文message=[%d] [%s]\n",singMessage.length(),singMessage);

			messageBody = singMessage.getBytes();
			messageHead1 = NetTool.getMessageHead(nodeid,singType,messageBody.length);
		}
		
		System.arraycopy(messageHead1, 0, messageHead, 0, messageHead1.length);
		return messageBody;
    }
}